package com.dlc.shop.user.platform.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.i18n.I18nMessage;
import com.dlc.shop.common.response.ServerResponseEntity;
import com.dlc.shop.common.util.BeanUtil;
import com.dlc.shop.common.util.PageParam;
import com.dlc.shop.user.common.dto.CostPerPopupDTO;
import com.dlc.shop.user.common.enums.PopupPageTypeEnum;
import com.dlc.shop.user.common.enums.PopupStatusEnum;
import com.dlc.shop.user.common.enums.PopupUserTypeEnum;
import com.dlc.shop.user.common.enums.PushFrequencyEnum;
import com.dlc.shop.user.common.model.CostPerPopup;
import com.dlc.shop.user.common.service.CostPerPopupService;
import com.dlc.shop.user.common.vo.CostPerPopupVO;
import com.dlc.shop.user.common.vo.PopupRelateVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 弹窗广告
 * @author TRACK
 */
@RestController("platformCostPerPopupController")
@RequestMapping("/p/cost_per_popup")
@Tag(name = "platform-弹窗广告")
@RequiredArgsConstructor
public class CostPerPopupController {

    private final CostPerPopupService costPerPopupService;

    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;

    @GetMapping("/page")
    @Operation(summary = "获取弹窗广告列表", description = "分页获取弹窗广告列表")
    @PreAuthorize("@pms.hasPermission('platform:popupAd:list')")
    public ServerResponseEntity<IPage<CostPerPopupVO>> page(PageParam<CostPerPopupVO> pageDTO, CostPerPopupDTO costPerPopupDTO) {
        costPerPopupDTO.setShopId(Constant.PLATFORM_SHOP_ID);
        IPage<CostPerPopupVO> costPerPopupPage = costPerPopupService.page(pageDTO, costPerPopupDTO);
        return ServerResponseEntity.success(costPerPopupPage);
    }

    @GetMapping
    @Operation(summary = "获取弹窗广告", description = "根据popupId获取弹窗广告")
    @PreAuthorize("@pms.hasPermission('platform:popupAd:view')")
    public ServerResponseEntity<CostPerPopupVO> getByPopupId(@RequestParam Long popupId) {
        CostPerPopupVO popup = costPerPopupService.getByPopupId(popupId);
        costPerPopupService.handleInfo(popup);
        return ServerResponseEntity.success(popup);
    }

    @PostMapping
    @Operation(summary = "保存弹窗广告", description = "保存弹窗广告")
    @PreAuthorize("@pms.hasPermission('platform:popupAd:save')")
    public ServerResponseEntity<Void> save(@Valid @RequestBody CostPerPopupDTO costPerPopupDTO) {
        if (BooleanUtil.isFalse(permission)) {
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.operate.auth"));
        }
        CostPerPopup costPerPopup = BeanUtil.map(costPerPopupDTO, CostPerPopup.class);
        costPerPopup.setPopupId(null);
        costPerPopup.setShopId(Constant.PLATFORM_SHOP_ID);
        costPerPopup.setStatus(PopupStatusEnum.NOT_START.value());
        checkInfo(costPerPopup);
        costPerPopupService.insert(costPerPopup);
        return ServerResponseEntity.success();
    }

    @PutMapping
    @Operation(summary = "更新弹窗广告", description = "更新弹窗广告")
    @PreAuthorize("@pms.hasPermission('platform:popupAd:update')")
    public ServerResponseEntity<Void> update(@Valid @RequestBody CostPerPopupDTO costPerPopupDTO) {
        if (BooleanUtil.isFalse(permission)) {
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.operate.auth"));
        }
        CostPerPopup costPerPopup = BeanUtil.map(costPerPopupDTO, CostPerPopup.class);
        checkInfo(costPerPopup);
        costPerPopupService.update(costPerPopup);
        return ServerResponseEntity.success();
    }

    @DeleteMapping
    @Operation(summary = "删除弹窗广告", description = "根据弹窗广告id删除弹窗广告")
    @PreAuthorize("@pms.hasPermission('platform:popupAd:delete')")
    public ServerResponseEntity<Void> delete(@RequestParam Long popupId) {
        if (BooleanUtil.isFalse(permission)) {
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.operate.auth"));
        }
        costPerPopupService.deleteById(popupId, Constant.PLATFORM_SHOP_ID);
        return ServerResponseEntity.success();
    }

    @PutMapping("/invalid")
    @Operation(summary = "失效弹窗广告", description = "根据弹窗广告id失效弹窗广告")
    @PreAuthorize("@pms.hasPermission('platform:popupAd:invalid')")
    public ServerResponseEntity<Void> invalid(@RequestParam Long popupId) {
        if (BooleanUtil.isFalse(permission)) {
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.operate.auth"));
        }
        costPerPopupService.invalid(popupId, Constant.PLATFORM_SHOP_ID);
        return ServerResponseEntity.success();
    }

    private void checkInfo(CostPerPopup costPerPopup) {
        if (!PopupPageTypeEnum.isSys(costPerPopup.getPageType())) {
            throw new YamiShopBindException("触发页面类型错误");
        }
        if (!PopupUserTypeEnum.isSys(costPerPopup.getUserType())) {
            throw new YamiShopBindException("推送用户类型错误");
        }
        if (!Objects.equals(costPerPopup.getUserType(), PopupUserTypeEnum.ALL_USER.value()) && CollUtil.isEmpty(costPerPopup.getUserLevelIds())) {
            throw new YamiShopBindException("关联等级不能为空");
        }
        if (Objects.equals(costPerPopup.getPushFrequency(), PushFrequencyEnum.CUSTOM.value())) {
            if (Objects.isNull(costPerPopup.getDayFrequency()) && StrUtil.isBlank(costPerPopup.getWeekFrequency())) {
                throw new YamiShopBindException("推送天数/周不能为空");
            }
            if (Objects.nonNull(costPerPopup.getDayFrequency()) && StrUtil.isNotBlank(costPerPopup.getWeekFrequency())) {
                throw new YamiShopBindException("推送天数/周不能同时存在");
            }
        }
        // 校验重复
        List<CostPerPopupVO> dbList = costPerPopupService.listByParam(costPerPopup);
        if (CollUtil.isEmpty(dbList)) {
            return;
        }
        boolean checkFrequency = Objects.equals(costPerPopup.getPushFrequency(), PushFrequencyEnum.CUSTOM.value()) && StrUtil.isNotBlank(costPerPopup.getWeekFrequency());
        if (!checkFrequency) {
            checkLevel(costPerPopup, dbList);
            return;
        }
        // 只有按周推送需要再校验一下周数重复
        for (CostPerPopupVO costPerPopupVO : dbList) {
            if (!Objects.equals(costPerPopupVO.getPushFrequency(), PushFrequencyEnum.CUSTOM.value()) || StrUtil.isBlank(costPerPopupVO.getWeekFrequency())) {
                checkLevel(costPerPopup, dbList);
            } else {
                // 按周推送的检查是否有重复周
                List<String> duplicateList = costPerPopupService.getDuplicateList(costPerPopup, costPerPopupVO);
                if (CollUtil.isNotEmpty(duplicateList)) {
                    checkLevel(costPerPopup, dbList);
                }
            }
        }
    }

    private static void checkLevel(CostPerPopup costPerPopup, List<CostPerPopupVO> dbList) {
        boolean duplicate = false;
        for (CostPerPopupVO costPerPopupVO : dbList) {
            if (!Objects.equals(costPerPopupVO.getUserType(), costPerPopup.getUserType())) {
                duplicate = true;
                break;
            }
            if (Objects.equals(costPerPopup.getUserType(), costPerPopupVO.getUserType()) && Objects.equals(costPerPopupVO.getUserType(), PopupUserTypeEnum.ALL_USER.value())) {
                duplicate = true;
                break;
            }
            List<Long> dbUserLevelIds = costPerPopupVO.getPopupRelateList().stream().map(PopupRelateVO::getUserLevelId).toList();
            List<Long> duplicateList = dbUserLevelIds.stream().filter(costPerPopup.getUserLevelIds()::contains).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(duplicateList)) {
                duplicate = true;
                break;
            }
        }
        if (duplicate) {
            throw new YamiShopBindException("已有重复弹窗广告");
        }
    }
}
